package main

import (
	"dataconvertserver/server/command"
	"dataconvertserver/server/configclass"
	"dataconvertserver/server/crontab"
	"dataconvertserver/server/service"
	"dataconvertserver/utils/ormdb"
	"fmt"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

	"gitlab.upchinaproduct.com/taf/tafgo/taf"
	"gitlab.upchinaproduct.com/taf/tafgo/taf/util/conf"

	"dataconvertserver/taf-protocol/CRM"
	"dataconvertserver/utils/taftool"
)

func main() {

	//初始化业务逻辑
	initServerErr := initServer()
	if initServerErr != nil {
		//初始化业务逻辑失败
		fmt.Printf("{initServerError err}|%s", initServerErr.Error())
		os.Exit(-1)
	}
	// Get server configclass
	cfg := taf.GetServerConfig()

	// New servant imp
	imp := new(DataConvertImp)
	err := imp.Init()
	if err != nil {
		fmt.Printf("DataConvertImp init fail, err:(%s)\n", err)
		os.Exit(-1)
	}
	// New servant
	app := new(CRM.DataConvert)
	// Register Servant
	app.AddServantWithContext(imp, cfg.App+"."+cfg.Server+".DataConvertObj")

	// Run application
	taf.Run()
}

//////////////////////////////////////////////////////// 初始化服务

// 配置文件
var Conf *conf.Conf

func initServer() error {

	//初始化服务配置
	fmt.Println("---------------initServer---------------")
	confName := "DataConvertServer.conf"
	if taftool.IsLocalEnv() {
		confName = "config/" + confName
	}

	//confName名称是什么
	fmt.Printf("{initServer confName}|%s\n", confName)
	var initErr error
	Conf, initErr = taftool.GetTafConfigByName(confName)
	if initErr != nil {
		fmt.Println("{initServerConfError confName}|", confName)
		return initErr
	}

	//初始化配置到结构体
	fmt.Println("---------------initConfigClass---------------")
	var rootMysql string = "mysql"
	var mysqlConfigValue configclass.MysqlConfig
	mysqlConfList := Conf.GetDomain(rootMysql)
	fmt.Printf("{initDbConf mysqlConfList}|%s\n", mysqlConfList)
	for _, mysqlConfId := range mysqlConfList {
		mysqlIdList := Conf.GetDomain(rootMysql + "/" + mysqlConfId)
		mysqlIdMap := Conf.GetMap(rootMysql + "/" + mysqlConfId)
		fmt.Printf("{initDbConf mysqlIdList}|%s\n", mysqlIdList)
		fmt.Printf("{initDbConf mysqlIdMap}|%s\n", mysqlIdMap)

		mysqlSourceString := "source"
		mysqlDestinationString := "destination"
		mysqlIdSource := Conf.GetMap(rootMysql + "/" + mysqlConfId + "/" + mysqlSourceString)
		mysqlIdDestination := Conf.GetMap(rootMysql + "/" + mysqlConfId + "/" + mysqlDestinationString)
		fmt.Printf("{initDbConf mysqlIdSource}|%s\n", mysqlIdSource)
		fmt.Printf("{initDbConf mysqlIdDestination}|%s\n", mysqlIdDestination)

		mysqlConfigValue.Status = mysqlIdMap["status"]
		mysqlConfigValue.Crontab = mysqlIdMap["crontab"]
		//封装Source配置到结构体
		var mysqlConfSource configclass.MysqlSource
		mysqlConfSource.Target = strings.TrimSpace(mysqlIdSource["target"])
		mysqlConfSource.DbPrefix = strings.TrimSpace(mysqlIdSource["db_prefix"])
		mysqlConfSource.TablePrefix = strings.TrimSpace(mysqlIdSource["table_prefix"])
		mysqlConfSource.DbQuantity, _ = strconv.Atoi(mysqlIdSource["db_quantity"])
		mysqlConfSource.TableQuantity, _ = strconv.Atoi(mysqlIdSource["table_quantity"])
		mysqlConfSource.IncrementDatetime = strings.TrimSpace(mysqlIdSource["increment_datetime"])
		mysqlConfSource.PageSize = strings.TrimSpace(mysqlIdSource["page_size"])
		mysqlConfSource.Sql = strings.TrimSpace(mysqlIdSource["sql"])
		mysqlConfigValue.Source = mysqlConfSource
		//封装Destination配置到结构体
		var mysqlDestination configclass.MysqlDestination
		mysqlDestination.Target = strings.TrimSpace(mysqlIdDestination["target"])
		mysqlDestination.Sql = strings.TrimSpace(mysqlIdDestination["sql"])
		mysqlConfigValue.Destination = mysqlDestination
		configclass.GetConfigManager().SetConfig(mysqlConfId, mysqlConfigValue)
	}

	//初始化数据库链接
	fmt.Println("---------------initMysqlConfig---------------")
	for mysqlConfId, MysqlConfig := range configclass.GetConfigManager().GetAllConfigs() {
		mysqlSourceConnTarget := strings.Split(MysqlConfig.Source.Target, ";")
		mysqlDestinationConnTarget := strings.Split(MysqlConfig.Destination.Target, ";")
		//处理源数据库
		if len(mysqlSourceConnTarget) > 4 {
			host := strings.TrimSpace(mysqlSourceConnTarget[0])
			port := strings.TrimSpace(mysqlSourceConnTarget[1])
			username := strings.TrimSpace(mysqlSourceConnTarget[2])
			password := strings.TrimSpace(mysqlSourceConnTarget[3])
			database := strings.TrimSpace(mysqlSourceConnTarget[4])

			mysqlConnStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, database)
			fmt.Printf("{initDbConf database^mysqlConnStr}|mysql|%s|%s\n", database, mysqlConnStr)
			initErr = ormdb.InitDb(mysqlConfId, mysqlConnStr, 0)
			if initErr != nil {
				fmt.Printf("{initDbError error}|db|%s\n", initErr.Error())
			}
		}

		//处理目标数据库
		if len(mysqlDestinationConnTarget) > 4 {
			host := strings.TrimSpace(mysqlDestinationConnTarget[0])
			port := strings.TrimSpace(mysqlDestinationConnTarget[1])
			username := strings.TrimSpace(mysqlDestinationConnTarget[2])
			password := strings.TrimSpace(mysqlDestinationConnTarget[3])
			database := strings.TrimSpace(mysqlDestinationConnTarget[4])

			mysqlConnStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", username, password, host, port, database)
			fmt.Printf("{initDbConf database^mysqlConnStr}|mysql|%s|%s\n", database, mysqlConnStr)
			initErr = ormdb.InitDb(mysqlConfId, mysqlConnStr, 1)
			if initErr != nil {
				fmt.Printf("{initDbError error}|db|%s\n", initErr.Error())
			}
		}
	}

	//输出所有已建立的连接
	ormdb.Output()

	//输出结构体变量
	configclass.GetConfigManager().Output()

	//初始化定时逻辑入口
	crontab.Init()

	//初始化业务逻辑入口
	service.Init()

	//信号
	taf.RegisterAdmin("v", command.Version)
	taf.RegisterAdmin("vs", command.Version)
	taf.RegisterAdmin("ver", command.Version)
	taf.RegisterAdmin("version", command.Version)
	taf.RegisterAdmin("help", command.Help)
	taf.RegisterAdmin("reload", command.HandleRawConvert)
	fmt.Println("{tafcmd regCMD}|start_colletor")

	//测试代码
	testFunc()

	fmt.Println("---------------initServerEnd---------------")
	return nil
}

func testFunc() {
	//在taf环境下不走这个函数
	if !taftool.IsLocalEnv() {
		return
	}

	//fmt.Println(utils.GetSimpleRandId())
	//延迟5s发送测试客户端请求
	timer := time.NewTimer(5 * time.Second)
	go func() {
		<-timer.C
		cmd := exec.Command("./build/bin/client")
		cmd.Start()
	}()

}
